package com.flute.framework.index;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.FSDirectory;

import com.flute.framework.LuceneDocumentBuilder;
import com.flute.framework.index.fieldbuilder.FieldFactor;
import com.flute.framework.index.fieldbuilder.FieldsRecordScorer;
import com.flute.framework.index.fieldbuilder.LuceneScoreFieldBuilder;
import com.flute.framework.index.fieldbuilder.StoreFieldBuilder;
import com.flute.framework.search.ISearcher;
import com.flute.framework.search.LayerSimilarity;
import com.flute.framework.search.strategy.PrefixSearchStrategy;
import com.flute.framework.search.strategy.SameSearchStrategy;
import com.flute.framework.search.strategy.SplitedSearchStrategy;
import com.flute.framework.stringprocessor.PinyinHeadersStringProcessor;
import com.flute.framework.stringprocessor.SameStringProcessor;
import com.flute.framework.stringprocessor.SplitStringProcessor;
import com.flute.framework.stringprocessor.SplitedPinyinHeadersStringProcessor;
import com.flute.tools.data.DataRecord;

public class NewFluteTester {
	public static void main(String[] args) throws Exception {
		IndexWriter writer = new IndexWriter(FSDirectory.open(new File(
				"search/D")), new WhitespaceAnalyzer(), true,
				MaxFieldLength.LIMITED);

		LuceneDocumentBuilder builder = getBuilder();

		for (DataRecord dr : getRecords()) {
			writer.addDocument((Document) builder.buildDocument(dr));
		}

		writer.optimize();
		writer.close();

		IndexSearcher searcher = new IndexSearcher(FSDirectory.open(new File(
				"search/D")));
		searcher.setSimilarity(new LayerSimilarity());
		TopDocs tds = searcher.search(getPayloadTermQuery("冰雨 刘德华", "a"), 10);
		System.out.println(tds.totalHits);
		for (int i = 0; i < tds.scoreDocs.length; i++) {
			ScoreDoc sds = tds.scoreDocs[i];
			System.out.print(sds.score + "  ");
			System.out.println(searcher.doc(sds.doc).getField("name_store")
					.stringValue());
		}
	}

	private static List<DataRecord> getRecords() {
		List<DataRecord> list = new ArrayList<DataRecord>();
		DataRecord dr = new DataRecord();
		dr.AddField("name", "刘德华");
		dr.AddField(IDocumentBuilder.DOCUMENT_ID, "1");
		// dr.AddField(IDocumentBuilder.ACTIVITY_FIELD, "abc,1");
		list.add(dr);

		dr = new DataRecord();
		dr.AddField("name", "刘德华 冰雨");
		dr.AddField(IDocumentBuilder.DOCUMENT_ID, "2");
		dr.AddField(IDocumentBuilder.ACTIVITY_FIELD, "true");
		list.add(dr);

		dr = new DataRecord();
		dr.AddField("name", "冰雨一直下");
		dr.AddField(IDocumentBuilder.DOCUMENT_ID, "4");
		dr.AddField(IDocumentBuilder.ACTIVITY_FIELD, "true");
		list.add(dr);

		dr = new DataRecord();
		dr.AddField("name", "刘德华 忘情水");
		dr.AddField(IDocumentBuilder.DOCUMENT_ID, "3");
		// dr.AddField(IDocumentBuilder.ACTIVITY_FIELD, "true");
		list.add(dr);

		return list;
	}

	@SuppressWarnings("unused")
	private static Query getSimpleQuery(String text) {
		return new TermQuery(new Term("name_split", text));
	}

	private static Query getPayloadTermQuery(String text, String sorter) {
		BooleanQuery bq = new BooleanQuery();

		SameSearchStrategy sss = new SameSearchStrategy();
		sss.setFieldName("name_same");
		Query q = (Query) sss
				.getQuery(text, sorter, 5 * ISearcher.SCORE_FACTOR);
		bq.add(q, Occur.SHOULD);

		SplitedSearchStrategy split = new SplitedSearchStrategy();
		split.setFieldName("name_split");
		q = (Query) split.getQuery(text, sorter, 4 * ISearcher.SCORE_FACTOR);
		bq.add(q, Occur.SHOULD);

		sss = new SameSearchStrategy();
		sss.setFieldName("name_header");
		q = (Query) sss.getQuery(text, sorter, 3 * ISearcher.SCORE_FACTOR);
		bq.add(q, Occur.SHOULD);

		split = new SplitedSearchStrategy();
		split.setFieldName("name_header_split");
		q = (Query) split.getQuery(text, sorter, 2 * ISearcher.SCORE_FACTOR);
		bq.add(q, Occur.SHOULD);

		PrefixSearchStrategy pss = new PrefixSearchStrategy();
		pss.setFieldName("name_same");
		q = (Query) pss.getQuery(text, sorter, 1 * ISearcher.SCORE_FACTOR);
		bq.add(q, Occur.SHOULD);

		sss = new SameSearchStrategy();
		sss.setFieldName(IDocumentBuilder.ACTIVITY_FIELD);
		Query query = (Query) sss.getQuery(text, sorter, ISearcher.SCORE_FACTOR
				* (2 + 10));
		bq.add(query, Occur.SHOULD);

		return bq;
	}

	private static LuceneDocumentBuilder getBuilder() {
		LuceneDocumentBuilder builder = new LuceneDocumentBuilder();
		StoreFieldBuilder store = new StoreFieldBuilder();
		store.setDataField("name");
		store.setDocField("name_store");
		builder.addFieldBuilder(store);

		LuceneScoreFieldBuilder sameScore = new LuceneScoreFieldBuilder();
		sameScore.setDataField("name");
		sameScore.setDocField("name_same");
		sameScore.setProcessor(new SameStringProcessor());
		builder.addFieldBuilder(sameScore);

		LuceneScoreFieldBuilder splitScore = new LuceneScoreFieldBuilder();
		splitScore.setDataField("name");
		splitScore.setDocField("name_split");
		splitScore.setProcessor(new SplitStringProcessor());
		builder.addFieldBuilder(splitScore);

		LuceneScoreFieldBuilder pinyinHeaderScore = new LuceneScoreFieldBuilder();
		pinyinHeaderScore.setDataField("name");
		pinyinHeaderScore.setDocField("name_header");
		pinyinHeaderScore.setProcessor(new PinyinHeadersStringProcessor());
		builder.addFieldBuilder(pinyinHeaderScore);

		pinyinHeaderScore = new LuceneScoreFieldBuilder();
		pinyinHeaderScore.setDataField("name");
		pinyinHeaderScore.setDocField("name_header_split");
		pinyinHeaderScore
				.setProcessor(new SplitedPinyinHeadersStringProcessor());
		builder.addFieldBuilder(pinyinHeaderScore);

		FieldsRecordScorer frs = new FieldsRecordScorer();
		frs.setName(1);
		frs.addFieldFactor(new FieldFactor("documentID", 1));
		builder.addSorter(frs);

		return builder;
	}

	// private static Query getTermQuery(String filed, String text) {
	// return new TermQuery(new Term(filed, text));
	// }
}
